package geektime.spring.springbucks.customerservice;

import geektime.spring.springbucks.customerservice.support.CustomConnectionKeepAliveStrategy;

import java.net.URI;
import java.net.URL;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.Banner.Mode;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.Resource;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

@Slf4j
@SpringBootApplication
public class CustomerServiceApplication {

    @Value("${security.key-store}")
    private Resource keyStore;
    @Value("${security.key-pass}")
    private String keyPass;

    public static void main(String[] args) {
        //		SpringApplication.run(CustomerServiceApplication.class, args);
        new SpringApplicationBuilder().sources(CustomerServiceApplication.class).bannerMode(Mode.OFF).web(WebApplicationType.NONE).run(args);
    }

    @Bean
    public HttpComponentsClientHttpRequestFactory requestFactory() {
        SSLContext sslContext = null;
        try {
            sslContext = SSLContextBuilder.create()
                    // 会校验证书
                    .loadTrustMaterial(keyStore.getURL(), keyPass.toCharArray())
                    // 放过所有证书校验
                    //          .loadTrustMaterial(null, (certificate, authType) -> true)
                    .build();
        } catch (Exception e) {
            log.error("Exception occurred while creating SSLContext.", e);
        }

        CloseableHttpClient httpClient = HttpClients.custom().evictIdleConnections(30, TimeUnit.SECONDS).setMaxConnTotal(200).setMaxConnPerRoute(20).disableAutomaticRetries()
                //         有 Keep-Alive 认里面的值，没有的话永久有效
                //        .setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE)
                //         换成自定义的
                .setKeepAliveStrategy(new CustomConnectionKeepAliveStrategy()).setSSLContext(sslContext).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).build();
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);

        return requestFactory;
    }

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder.setConnectTimeout(Duration.ofMillis(1000)).setReadTimeout(Duration.ofMillis(5000)).requestFactory(this::requestFactory).build();
    }

}
